using System;
using System.Collections.Generic;
using System.Data;
using Loogn.OrmLite;
using Loogn.OrmLite.MySql;
using MySql.Data.MySqlClient;

namespace ShortUrl
{
    public class Urls
    {
        public long Id { get; set; }
        public string Key { get; set; }
        public string Url { get; set; }
        public DateTime AddTime { get; set; }
        public DateTime ExpireTime { get; set; }


        static readonly Random random = new Random();

        static readonly char[] charsArray =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray();

        static readonly int charsArrayLength = charsArray.Length;

        static string GenerateKey(int length)
        {
            var result = new char[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = charsArray[random.Next(charsArrayLength)];
            }

            return new string(result);
        }

        public static string NewKey()
        {
            var key = GenerateKey(6);
            while (CacheData.ContainsKey(key))
            {
                key = GenerateKey(6);
            }

            return key;
        }


        private static Dictionary<string, Urls> CacheData = new Dictionary<string, Urls>(100);

        private static IDbConnection Open()
        {
            return new MySqlConnection(Config.ConnStr);
        }

        public static long AddUrl(Urls urls)
        {
            if (CacheData.ContainsKey(urls.Key))
            {
                return 0;
            }

            using var db = Open();
            var id = db.Insert(urls, true);
            if (id > 0)
            {
                urls.Id = id;
                CacheData[urls.Key] = urls;
            }

            return id;
        }

        public static void ReflashUrls()
        {
            using var db = Open();
            db.DeleteWhere<Urls>(DictBuilder.LT("ExpireTime", DateTime.Now));
            var list = db.Select<Urls>();
            CacheData.Clear();
            foreach (var item in list)
            {
                CacheData[item.Key] = item;
            }
        }

        public static Urls GetUrl(string key)
        {
            if (CacheData.TryGetValue(key, out Urls url))
            {
                return url;
            }

            return null;
        }
    }
}